home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / sbdetect.asm < prev   
Encoding:
Assembly Source File  |  1994-04-25  |  9.5 KB  |  382 lines

  1. This is some TASM code for detecting the IRQ and interupt of a Sound Blaster
  2. card.  Use it well!  
  3.  
  4. The Bunny Hunter
  5.  
  6. --------------------------------- Cut Here -------------------------------
  7.  
  8. WAIT_TIME       EQU     000FFh
  9. DSP_INTRQ_CMD   EQU     000F2h
  10.  
  11. DATA    SEGMENT WORD PUBLIC
  12.  
  13.         EXTRN   SBInt   : WORD;
  14.         EXTRN   SBIrq   : WORD;
  15.  
  16.         ORG_INT2_ADDX   DD 0;
  17.         ORG_INT3_ADDX   DD 0;
  18.         ORG_INT5_ADDX   DD 0;
  19.         ORG_INT7_ADDX   DD 0;
  20.  
  21. DATA    ENDS
  22.  
  23. CODE    SEGMENT WORD    PUBLIC
  24.     ASSUME    CS:CODE,DS:DATA
  25.  
  26. ;════════════════════════════════════════════════════════
  27. ;
  28. ; ResetDSP - reset the DSP
  29. ;
  30. ;════════════════════════════════════════════════════════
  31.  
  32. ResetDSP        PROC
  33.  
  34.                 MOV    DX,SBInt
  35.                 ADD    DL,6            ; DX = DSP reset port 2x6h
  36.                 MOV    AL,1
  37.                 OUT    DX,AL           ; write 1, then wait 3 micro-seconds
  38.  
  39.                 IN     AL,DX           ; read value from DSP
  40. RDSP05:
  41.                 INC    AL
  42.                 JNZ    RDSP05          ; wait until AL = 0
  43.  
  44.                 OUT    DX,AL           ; write 0
  45.  
  46.                 MOV    CL,20H          ; set reset timeout value
  47.  
  48. RDSP10:
  49.                 CALL   ReadDSPTime     ; read from DSP
  50.                 CMP    AL,0AAH         ; if byte is 0AAh then
  51.                 JE     RDSP20          ;   DSP is reset, exit
  52.  
  53.                 LOOP   RDSP10          ; not reset, try again
  54.  
  55.                 MOV    AX,2            ; set I/O failure error
  56.                 JMP    SHORT RDSP90    ; exit;
  57.  
  58. RDSP20:
  59.                 XOR    AX,AX           ; clear AX, no error
  60.  
  61. RDSP90:
  62.                 OR     AX,AX           ; set flags for return
  63.  
  64.                 RET
  65.  
  66. ResetDSP        ENDP
  67.  
  68. ;════════════════════════════════════════════════════════
  69. ;
  70. ; ReadDSPTime   - read from DSP with timeout
  71. ;
  72. ;════════════════════════════════════════════════════════
  73.  
  74. ReadDSPTime     PROC
  75.  
  76.                 PUSH   CX
  77.                 PUSH   DX
  78.  
  79.                 MOV    DX,SBInt
  80.                 ADD    DL,0EH          ; DX = DSP data available port 2xEh
  81.  
  82.                 MOV    CX,WAIT_TIME    ; load timeout value into CX
  83.  
  84. RDT10:
  85.                 IN     AL,DX           ; check to see if DSP is ready
  86.                 OR     AL,AL
  87.                 JS     RDT20           ; if sign set, then DSP read ready
  88.  
  89.                 LOOP   RDT10           ; not ready, keep waiting
  90.  
  91.                 STC                    ; set error, DSP read timeout
  92.                 JMP    SHORT RDT90     ; exit
  93.  
  94. RDT20:
  95.                 SUB    DL,4            ; DX = DSP read data port 2xAh
  96.                 IN     AL,DX           ; read byte from DSP
  97.                 CLC                    ; clear error
  98.  
  99. RDT90:
  100.                 POP    DX
  101.                 POP    CX
  102.  
  103.                 RET
  104.  
  105. ReadDSPTime     ENDP
  106.  
  107. ;════════════════════════════════════════════════════════
  108. ;
  109. ; CheckSBInt - detect DMA interrupt
  110. ;
  111. ;════════════════════════════════════════════════════════
  112.  
  113. PUBLIC          CheckSBInt
  114.  
  115. CheckSBInt      PROC   FAR
  116.  
  117.                 push   bp
  118.                 mov    bp,sp
  119.  
  120.                 MOV    AL,2                           ; setup end of DMA
  121.                 MOV    DX,OFFSET DUMMY_DMA_INT2       ; interrupts for all
  122.                 MOV    BX,OFFSET DATA:ORG_INT2_ADDX   ; possible IRQs
  123.                 CALL   SetupInterrupt                 ; (2, 3, 5, and 7)
  124.  
  125.                 MOV    AL,3
  126.                 MOV    DX,OFFSET DUMMY_DMA_INT3
  127.                 MOV    BX,OFFSET DATA:ORG_INT3_ADDX
  128.                 CALL   SetupInterrupt
  129.  
  130.                 MOV    AL,5
  131.                 MOV    DX,OFFSET DUMMY_DMA_INT5
  132.                 MOV    BX,OFFSET DATA:ORG_INT5_ADDX
  133.                 CALL   SetupInterrupt
  134.  
  135.                 MOV    AL,7
  136.                 MOV    DX,OFFSET DUMMY_DMA_INT7
  137.                 MOV    BX,OFFSET DATA:ORG_INT7_ADDX
  138.                 CALL   SetupInterrupt
  139.  
  140.                 MOV    SBIrq,0          ; reset current IRQ
  141.  
  142.                 MOV    DX,SBInt
  143.                 ADD    DX,0CH           ; DX = DSP write port 2xCh
  144.                 MOV    AL,DSP_INTRQ_CMD ; AL = interrupt request command
  145.                 CALL   WriteDSP         ; write command to DSP
  146.  
  147.                 XOR    AX,AX           ; assume success
  148.                 MOV    CX,WAIT_TIME    ; load timeout value into CX
  149.                 CLD
  150.  
  151. VI10:
  152.                 CMP    SBIrq,0         ; see if interrupt has been changed
  153.                 JNE    VI90            ; if so, continue
  154.  
  155.                 LOOP   VI10            ; if not, keep waiting
  156.  
  157.                 MOV    AX,0FFh         ; set DMA failure error
  158.  
  159. VI90:
  160.                 PUSH   AX              ; save result variable
  161.  
  162.                 MOV    AL,2                          ; restore end of DMA
  163.                 MOV    BX,OFFSET DATA:ORG_INT2_ADDX  ; interrupts
  164.                 CALL   RestoreInterrupt
  165.  
  166.                 MOV    AL,3
  167.                 MOV    BX,OFFSET DATA:ORG_INT3_ADDX
  168.                 CALL   RestoreInterrupt
  169.  
  170.                 MOV    AL,5
  171.                 MOV    BX,OFFSET DATA:ORG_INT5_ADDX
  172.                 CALL   RestoreInterrupt
  173.  
  174.                 MOV    AL,7
  175.                 MOV    BX,OFFSET DATA:ORG_INT7_ADDX
  176.                 CALL   RestoreInterrupt
  177.  
  178.                 POP    AX              ; restore result
  179.  
  180.                 OR     AX,AX
  181.  
  182.                 mov    sp,bp
  183.                 pop    bp
  184.  
  185.                 RET
  186.  
  187. CheckSBInt      ENDP
  188.  
  189. ;════════════════════════════════════════════════════════
  190. ;
  191. ;  WriteDSP
  192. ;
  193. ;════════════════════════════════════════════════════════
  194.  
  195. WriteDSP        PROC
  196.  
  197.                 PUSH   CX
  198.  
  199.                 MOV    AH,AL           ; save value in AL for later
  200.  
  201.                 MOV    CX,WAIT_TIME
  202.  
  203. WD10:
  204.                 IN     AL,DX           ; check to see if DSP is ready
  205.                 OR     AL,AL
  206.                 JNS    WD20            ; if sign set, DSP not write ready
  207.                 LOOP   WD10
  208.  
  209. WD20:
  210.                 MOV    AL,AH           ; restore AL
  211.                 OUT    DX,AL           ; send byte to DSP
  212.  
  213.                 POP    CX
  214.  
  215.                 RET
  216.  
  217. WriteDSP        ENDP
  218.  
  219. ;════════════════════════════════════════════════════════
  220. ;
  221. ; SetupInterrupt
  222. ;
  223. ;════════════════════════════════════════════════════════
  224.  
  225. SetupInterrupt  PROC
  226.  
  227.                 PUSH   BX
  228.                 PUSH   CX
  229.                 PUSH   DX
  230.  
  231.                 CLI
  232.  
  233.                 MOV    CL,AL           ; preserve interrupt number for use
  234.  
  235.                 ADD    AL,8            ; calculate interrupt vector addx
  236.                 CBW
  237.                 SHL    AL,1
  238.                 SHL    AL,1
  239.                 MOV    DI,AX
  240.  
  241.                 PUSH   ES              ; setup and preserve interrupt
  242.                 XOR    AX,AX
  243.                 MOV    ES,AX
  244.                 MOV    AX,ES:[DI]
  245.                 MOV    [BX],AX
  246.                 MOV    ES:[DI],DX
  247.  
  248.                 MOV    AX,ES:[DI+2]
  249.                 MOV    [BX+2],AX
  250.                 MOV    ES:[DI+2],CS
  251.  
  252.                 POP    ES
  253.  
  254.                 MOV    AH,1            ; enable interrupt control mask-bit
  255.                 SHL    AH,CL
  256.                 NOT    AH
  257.  
  258.                 IN     AL,21H
  259.                 AND    AL,AH
  260.                 OUT    21H,AL
  261.  
  262.                 STI
  263.  
  264.                 POP    DX
  265.                 POP    CX
  266.                 POP    BX
  267.  
  268.                 RET
  269.  
  270. SetupInterrupt  ENDP
  271.  
  272.  
  273. ;════════════════════════════════════════════════════════
  274. ;
  275. ; RestoreInterrupt
  276. ;
  277. ; ENTRY: AL = INTERRUPT NUM
  278. ;        BX = offset to stored addx
  279. ;
  280. ;════════════════════════════════════════════════════════
  281.  
  282. RestoreInterrupt PROC
  283.  
  284.                 CLI
  285.  
  286.                 MOV    CL,AL
  287.  
  288.                 ADD    AL,8            ; calculate interrupt vector addx
  289.                 CBW
  290.                 SHL    AL,1
  291.                 SHL    AL,1
  292.                 MOV    DI,AX
  293.  
  294.                 PUSH   ES              ; restore interrupt vector
  295.                 XOR    AX,AX
  296.                 MOV    ES,AX
  297.                 MOV    AX,[BX]
  298.                 MOV    ES:[DI],AX
  299.  
  300.                 MOV    AX,[BX+2]
  301.                 MOV    ES:[DI+2],AX
  302.  
  303.                 POP    ES
  304.  
  305.                 MOV    AH,1
  306.                 SHL    AH,CL
  307.  
  308.                 IN     AL,21H
  309.                 OR     AL,AH
  310.                 OUT    21H,AL
  311.  
  312.                 STI
  313.  
  314.                 RET
  315.  
  316. RestoreInterrupt ENDP
  317.  
  318. ;════════════════════════════════════════════════════════
  319. ;
  320. ; DUMMY INTERRUPTS - used for interrupt detection
  321. ;
  322. ;════════════════════════════════════════════════════════
  323.  
  324. DUMMY_DMA_INT2  PROC   FAR
  325.  
  326.                 PUSH   DX
  327.                 MOV    DX,2
  328.                 JMP    SHORT DUMMY_DMA_ISR
  329.  
  330. DUMMY_DMA_INT2  ENDP
  331.  
  332.  
  333. DUMMY_DMA_INT3  PROC   FAR
  334.  
  335.                 PUSH   DX
  336.                 MOV    DX,3
  337.                 JMP    SHORT DUMMY_DMA_ISR
  338.  
  339. DUMMY_DMA_INT3  ENDP
  340.  
  341.  
  342. DUMMY_DMA_INT5  PROC   FAR
  343.  
  344.                 PUSH   DX
  345.                 MOV    DX,5
  346.                 JMP    SHORT DUMMY_DMA_ISR
  347.  
  348. DUMMY_DMA_INT5  ENDP
  349.  
  350.  
  351. DUMMY_DMA_INT7  PROC   FAR
  352.  
  353.                 PUSH   DX
  354.                 MOV    DX,7
  355.  
  356. DUMMY_DMA_ISR:
  357.                 PUSH   AX
  358.                 PUSH   DS
  359.  
  360.                 MOV    AX,DATA
  361.                 MOV    DS,AX
  362.  
  363.                 MOV    SBIrq,DX        ; update interrupt variable with
  364.                                        ; number of interrupt called
  365.                 MOV    DX,SBInt
  366.                 ADD    DX,0EH          ; DX = DSP data available port 2xEh
  367.                 IN     AL,DX           ; acknowledge DSP interrupt
  368.  
  369.                 MOV    AL,20H          ; send EOI (end of interrupt) to
  370.                 OUT    20H,AL          ; interrupt controller port 20h
  371.  
  372.                 POP    DS
  373.                 POP    AX
  374.                 POP    DX
  375.                 IRET                   ; interrupt return
  376.  
  377. DUMMY_DMA_INT7  ENDP
  378.  
  379. CODE    ENDS
  380.  
  381.     END
  382.